package com.hugoo.form.slt;

import com.hugoo.ajxl.util.ExcelUtils;
import com.hugoo.core.Conf;
import com.hugoo.core.db.DBC;
import com.hugoo.core.db.HSF;
import com.hugoo.core.slt.AcFwd;
import com.hugoo.core.slt.Action;
import com.hugoo.core.util.TL;
import com.hugoo.form.buzz.CacheProc;
import com.hugoo.form.sql.SqlProc;
import com.hugoo.form.xo.XForm;
import com.hugoo.form.xo.XHandle;
import com.hugoo.rpt.ExpPageInfo;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 *
 * @author Lovelock.Chan
 */
public class FormAction extends Action {

    @Override
    public AcFwd exec(HttpServletRequest request, HttpServletResponse response) {
        if (super.checkPara(request, response)) {
            //
            String px[] = _sid.split("-"), p;
            if (px.length != 2) {
                log.error("传入的请求指数值节点错误,SID无法正常识别->" + _sid);
                return null;
            }
            XForm xf = Conf.getXForm(px[0]);
            log.debug("Loading handle ->" + px[1]);
            XHandle handle = xf.getXHandle(px[1]);
            if (handle == null) {
                this.writeDataToClient(response, "<script>alert('系统未配置相关服务，详请联系管理员!')</script>");
                return null;
            }
            Map m = this.parsePara(request);//取得参数Map集合
            //-----处理文件上传部分
            if (ServletFileUpload.isMultipartContent(request)) {
                try {
                    log.debug("提交表单包括大文件媒体信息....");
                    uploadMultipartContent(request, m);
                } catch (Exception e) {
                    log.warn("上传表单附件出错！", e);
                }
            }
            {//日志参数集合
                log.info("传入的参数集合如下：\n\t" + m);
            }
            //--------------------------
            if (checkPower(handle)) {//存在无记录的情况，需要单独 处理
                SqlProc sp = new SqlProc(handle);
                if (XHandle.RtnYpe.CST == handle.getRtnYpe()) {
                    if (handle.isCacheRST()) {//如果支持结果集缓存
                        String key = CacheProc.getCacheKeys(handle, m);
                        if (CacheProc.haveCacheData(key)) {
                            //缓存
                            this.writeDataToClient(response, CacheProc.cacheData(key));
                            log.debug("缓存命中...->KEY:" + key);
                        } else {
                            m = sp.proc(m);
                            String rtn = sp.prsRtnData(m);
                            //缓存
                            CacheProc.cacheData(key, rtn);
                            log.info("缓存成功!-->" + key);
                            //
                            this.writeDataToClient(response, rtn);
                            if (TL.isNotEmpty(handle.getSaveCList())) {
                                this.cacheList(request, m, handle.getSaveCList());
                            }
                            if (TL.isNotEmpty(handle.getClearCList())) {
                                this.clearCacheList(request, handle.getClearCList());
                            }
                        }
                    } else {
                        //---------以下为不支持缓存结果集的处理方式-------------
                        m = sp.proc(m);
                        this.writeDataToClient(response, sp.prsRtnData(m));
                        if (TL.isNotEmpty(handle.getSaveCList())) {
                            this.cacheList(request, m, handle.getSaveCList());
                        }
                        if (TL.isNotEmpty(handle.getClearCList())) {
                            this.clearCacheList(request, handle.getClearCList());
                        }
                    }
                    return null;
                } else if (XHandle.RtnYpe.PGE == handle.getRtnYpe()) {
                    m = sp.proc(m);
                    Set<String> ks = m.keySet();
                    for (String k : ks) {
                        request.setAttribute(k, m.get(k));
                    }
                    if (TL.isNotEmpty(handle.getSaveCList())) {
                        this.cacheList(request, m, handle.getSaveCList());
                    }
                    if (TL.isNotEmpty(handle.getClearCList())) {
                        this.clearCacheList(request, handle.getClearCList());
                    }
                    return new AcFwd(sp.prsRtnData(m));
                } else if (XHandle.RtnYpe.TXT == handle.getRtnYpe() || XHandle.RtnYpe.XLS == handle.getRtnYpe()
                        || XHandle.RtnYpe.XLSX == handle.getRtnYpe()) {
                    //若为TXT文件写出形式
                    ExpPageInfo pi = sp.procByExpModl(m, handle.getRtnYpe());
                    new DBC().loadPageInfo(pi);
                    writeDataToClient(request, response, pi.getFile(), pi.getFileName());
                } else if (XHandle.RtnYpe.XLST == handle.getRtnYpe()) {
                    String xslt = handle.getXslt();
                    if (TL.isEmpty(xslt) || this.getClass().getResource(xslt) == null) {
                        log.warn("无效的XLS模板配置！");
                        super.writeDataToClient(response, "配置的XLS导出文件模板无效！");
                    } else {
                        xslt = this.getClass().getResource(xslt).getPath();
                        log.debug("模板路径：" + xslt);
                        //定制模板导出
                        m = sp.proc(m);
                        try {
                            File tmp = File.createTempFile(UUID.randomUUID().toString(), ".xls");
                            FileOutputStream out = new FileOutputStream(tmp);
                            ExcelUtils.export(xslt, m, out);
                            super.writeDataToClient(request, response, tmp, handle.getFileName());
                        } catch (Exception e) {
                            log.warn("处理导出文件出错！", e);
                            super.writeDataToClient(response, "配置的XLS导出文件模板无效！");
                        }
                    }
                }
            } else {
                //无操作权限
            }
        }
        return null;
    }

    private boolean checkPower(XHandle handle) {
        return true;
    }

    private void uploadMultipartContent(HttpServletRequest request, Map m) throws FileUploadException, Exception {
        String spc = Conf.getBaseProp(Conf._imp_file_space);
        DiskFileItemFactory factory = new DiskFileItemFactory(4 * 1024 * 1024, new File(spc));
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
        upload.setSizeMax(3000 * 1024 * 1024);
        List<FileItem> fileItems = upload.parseRequest(request);
        String name, scod, fname, ext, est = null;
        long size;
        File f;
        for (FileItem fi : fileItems) {
            if (fi.isFormField()) {
                if (fi.getFieldName() != null) {
                    m.put(fi.getFieldName().toUpperCase(), fi.getString("utf-8"));
                }
                continue;
            }
            fname = "FILE_" + fi.getFieldName().toUpperCase();
            size = fi.getSize();
            name = fi.getName();
            if (size == 0 || name == null) {
                log.info("文件名为空或者文件对象不存在!");
                continue;
            }
            name = name.substring(name.lastIndexOf("/") + 1).substring(name.lastIndexOf("\\") + 1);//解决名字长的问题
            //获取文件扩展类型名称如（jsp,word...）
            ext = name.indexOf(".") > 0 ? name.substring(name.lastIndexOf(".")) : ".tmp";
            scod = TL.socd();
            f = initFile(scod, ext);
            fi.write(f);//存储文件
            m.put(fname, scod);
            saveFileMetaInfo(fname, scod, size, name, f.getAbsolutePath());
        }
    }

    private File initFile(String uuid, String ext) {
        String basepath = Conf.getBaseProp(Conf._imp_file_space);
        String mpath = TL.format(new Date(), "/yyyy/MM/");
        String bash = basepath + mpath;
        File baseFile = new File(bash);
        if (!baseFile.exists()) {
            baseFile.mkdirs();
        }
        return new File(bash + uuid + ext);
    }

    /**
     * create table meta_file_upload(fname varchar(50),scod varchar(10) primary
     * key ,fsize number,oname varchar(200),path varchar(200))
     *
     * @param fname
     * @param scod
     * @param size
     * @param name
     * @param absolutePath
     */
    private void saveFileMetaInfo(String fname, String scod, long size, String name, String absolutePath) {
        HSF.excute("", "insert into meta_file_upload(fname,scod,fsize,oname,path) values ('" + fname + "','" + scod + "'," + size + ",'" + name + "','" + absolutePath + "')");
    }

    /**
     * *
     * 缓存列表，存储值为全字段大写，取值为全字段大写
     *
     * @param request
     * @param m
     * @param cacheList
     */
    private void cacheList(HttpServletRequest request, Map m, String cacheList) {
        String cl[] = cacheList.split(",");
        HttpSession sess = request.getSession();
        for (String c : cl) {
            if ("SYSUSER".equalsIgnoreCase(c)) {
                continue;
            }
            log.info("缓存成功->" + c.toUpperCase());
            sess.setAttribute(c.toUpperCase(), m.get(c.toUpperCase()));
        }
    }

    private void clearCacheList(HttpServletRequest request, String clearCList) {
        String cl[] = clearCList.split(",");
        HttpSession sess = request.getSession();
        for (String c : cl) {
            if ("SYSUSER".equalsIgnoreCase(c)) {
                continue;
            }
            log.info("清除缓存成功->" + c.toUpperCase());
            sess.removeAttribute(c.toUpperCase());
        }
    }
}
